package crud.template;

import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.List;
import java.util.Objects;

public class JSONTemplate {


    public static JSONObject buildTemplate(JSONObject template, JSONObject param) {
        JSONObject request = new JSONObject(true);
        for (String key : template.keySet()) {
            Object value = template.get(key);
            if (value instanceof JSONObject) {
                JSONObject tmpSubNode = buildTemplate((JSONObject) value, param);
                request.put(key, tmpSubNode);

            } else if (value instanceof JSONArray) {
                JSONArray tmpSubArray = new JSONArray();
                for (Object arrayItem : (JSONArray) value) {
                    JSONObject tmpSubNode = buildTemplate((JSONObject) arrayItem, param);
                    tmpSubArray.add(tmpSubNode);
                }
                request.put(key, tmpSubArray);
            } else {
                String nodeValue = template.getString(key);
                if (Objects.equals(key, "&") && Objects.equals(nodeValue, "$$")) //值字段全部替换
                {
                    request.putAll(param);
                } else {
                    String reg = "\\$\\{(.*?)\\}";
                    List<String> templateParamList = ReUtil.findAll(reg, nodeValue, 0);
                    if (!templateParamList.isEmpty()) {
                        for (String templateParamName : templateParamList) {
                            String paramName = StrUtil.sub(templateParamName, 2, -1).trim();
                            if (param.containsKey(paramName)) {
                                Object paramValue = param.get(paramName);
                                request.put(key, paramValue);
                            }
                        }
                    } else {
                        request.put(key, nodeValue);
                    }
                }

            }
        }
        return request;
    }


    static private JSONObject parserTableNode(JSONObject tableNode) {
        if (tableNode == null) {
            return null;
        }
        //处理@like标签
        if (tableNode.containsKey("@like")) {
            String[] likeList = tableNode.getString("@like").split(","); //模糊查询字段
            tableNode.remove("@like");
            //模糊匹配处理
            for (String likeField : likeList) {
                if (tableNode.containsKey(likeField)) {
                    String value = tableNode.getString(likeField);
                    String newKey = likeField + "$";
                    String newValue = "%" + value + "%";
                    tableNode.put(newKey, newValue);
                    tableNode.remove(likeField);
                }
            }
        }

        //处理orderBy,orderDir标签
        if (tableNode.containsKey("orderBy")) {
            String orderBy = tableNode.getString("orderBy");
            String orderDir = tableNode.getString("orderDir");

            if (orderDir != null && orderDir.equals("asc")) {
                tableNode.put("@order", orderBy + "+");
            } else {
                tableNode.put("@order", orderBy + "-");
            }

        }

        return tableNode;
    }

    public static JSONObject buildGetTemplate(JSONObject template, JSONObject param) {

        //处理表
        JSONObject req = template.getJSONObject("[]");
        for (String tableName : req.keySet()) {
            //表名称必须是大写开头
            if (!Character.isUpperCase(tableName.charAt(0))) {
                continue;
            }
            JSONObject tableNode = parserTableNode(req.getJSONObject(tableName));
            req.put(tableName, tableNode);
        }

        //放在最后面 APIJSON查询BUG
        if (template.containsKey("total@")) {
            String total = template.getString("total@");
            template.remove("total@");
            template.put("total@", total);
        }

        return buildTemplate(template, param);
    }

    public static JSONObject buildListTemplate(JSONObject template, JSONObject param) {
        JSONObject queryTemplate = template.getJSONObject("[]");
        for (String tableName : queryTemplate.keySet()) {
            //表名称大写开头,小写的为其他查询参数
            if (!Character.isUpperCase(tableName.charAt(0))) {
                continue;
            }

            JSONObject tableNode = parserTableNode(queryTemplate.getJSONObject(tableName));
            queryTemplate.put(tableName, tableNode);

        }

        return buildTemplate(template, param);
    }

    public static JSONObject buildRowTemplate(JSONObject template, JSONObject param) {
        for (String tableName : template.keySet()) {
            //表名称大写开头,小写的为其他查询参数
            if (!Character.isUpperCase(tableName.charAt(0))) {
                continue;
            }

            JSONObject tableNode = parserTableNode(template.getJSONObject(tableName));
            template.put(tableName, tableNode);
        }

        return buildTemplate(template, param);
    }

    public static JSONObject buildAddTemplate(JSONObject template, JSONObject param) {
        template.remove("@primaryKey");
        return buildTemplate(template, param);
    }

    public static JSONObject buildEditTemplate(JSONObject template, JSONObject param) {
        template.remove("@primaryKey");
        template.remove("@idField");
        return buildTemplate(template, param);
    }

    public static JSONObject buildDeleteTemplate(JSONObject template, JSONObject param) {
        return buildTemplate(template, param);
    }

}
